package progma.lang.compiler;

import static org.objectweb.asm.Opcodes.*;

import java.util.List;

import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.TreeNodeStream;
import org.antlr.runtime.tree.TreeParser;
import org.objectweb.asm.Type;

import progma.utils.Util;

public abstract class ProgmaBaseTreeParser extends TreeParser {

	protected BytecodeGenerator bg = new BytecodeGenerator();
	private boolean inited = false;
	protected static int anonCount = 0;
	protected SymbolTable st;

	public ProgmaBaseTreeParser(TreeNodeStream input) {
		super(input);
	}

	public ProgmaBaseTreeParser(TreeNodeStream input,
			RecognizerSharedState state) {
		super(input, state);
	}

	// ////////////////////////////////////////////////////////////////////

	protected void startClass(String name) {
		bg.start(name, ACC_PUBLIC + ACC_SUPER, "java/lang/Object", null);
		inited = true;
	}

	protected void checkInitedClass() {
		if (!inited) {
			bg.start("Progma$class" + anonCount++, ACC_PUBLIC + ACC_SUPER,
					"Ljava/lang/Object", null);
			inited = true;
		}
	}

	protected void newVariable(String name) {
		bg.newVariable(Util.toJavaName(name), ACC_PUBLIC + ACC_STATIC,
				Type.getDescriptor(Object.class));
	}

	protected void newFunction(String name, List<?> pars) {
		bg.startFunction(Util.toJavaName(name), ACC_PUBLIC + ACC_STATIC,
				Util.mountFunctionDesc(pars));
	}
	
	protected void endFunction() {
		bg.endFunction();
	}

	protected void newClass(String name, List<?> fields) {
		bg.newClass(Util.toJavaName(name), ACC_PUBLIC, "java/lang/Object", null);
		for (Object field : fields) {
			String text = ((CommonTree) field).getText();
			bg.newClassField(Util.toJavaName(text), ACC_PUBLIC,
					Type.getDescriptor(Object.class));
		}
		bg.endClass();
	}

	public BytecodeGenerator getGenerator() {
		return bg;
	}

	public void setSymbolTable(SymbolTable st) {
		this.st = st;
	}
}
